﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk;
using System.Xml;
using System.Xml.Linq;
using Ionic.Zlib;

namespace VS4CRM.Lib.Services
{
    /// <summary>
    /// The class incapsulates all operations can be done with customizations
    /// </summary>
    public class Customizations
    {
        public CrmService Service { get; private set; }

        // ================== Methods =======================

        #region Construction
        /// <summary>
        /// Constructs object to work with crm customizations
        /// </summary>
        /// <param name="service">Reference to crm servce</param>
        public Customizations(CrmService service)
        {
            this.Service = service;
        }
        #endregion

        #region Import
        /// <summary>
        /// Imports customization 
        /// </summary>
        /// <returns>True if import completed successfully</returns>
        public bool Import(string parameterXML, string customization)
        {
            ImportXmlRequest request = new ImportXmlRequest();
            request.ParameterXml = parameterXML.ToLower();
            request.CustomizationXml = customization;
            ImportXmlResponse response = this.Service.Execute(request) as ImportXmlResponse;
            return response != null;
        }
        #endregion

        #region ImportAllZip
        /// <summary>
        /// Import all customizations from zip file specified
        /// </summary>
        /// <param name="filePath">Zip file to import customizations from</param>
        public bool ImportAllZip(string filePath)
        {
            byte[] compressedXML = File.ReadAllBytes(filePath);

            // Create the request.
            ImportCompressedAllXmlRequest request = new ImportCompressedAllXmlRequest();

            // Assign the compressed data
            request.CompressedCustomizationXml = compressedXML;

            this.Service.Execute(request);

            return true;
        }
        #endregion

        #region ImportAllZip
        /// <summary>
        /// Import all customizations from zip file specified
        /// </summary>
        /// <param name="filePath">Zip file to import customizations from</param>
        public bool ImportAllZip(byte[] customizations)
        {

            // Create the request.
            ImportCompressedAllXmlRequest request = new ImportCompressedAllXmlRequest();

            // Assign the compressed data
            request.CompressedCustomizationXml = customizations;

            this.Service.Timeout = 1000000;
            // Execute the request.
            ImportCompressedAllXmlResponse response = (ImportCompressedAllXmlResponse)this.Service.Execute(request);
            return true;
        }
        #endregion

        #region ImportAllXml
        /// <summary>
        /// Import all customizations from xml file specified
        /// </summary>
        /// <param name="filePath">Path to the customizations file to import</param>
        public void ImportAllXmlFromFile(string filePath)
        {
            string importXml = File.ReadAllText(filePath);

            // Create the request.
            ImportAllXmlRequest importRequest = new ImportAllXmlRequest();

            // Tell the request where the temporary XML file is located.
            importRequest.CustomizationXml = importXml;

            // Execute the import.
            ImportAllXmlResponse importResponse = (ImportAllXmlResponse)this.Service.Execute(importRequest);
        }
        #endregion

        #region ImportAllXml
        /// <summary>
        /// Import all customizations from xml file specified
        /// </summary>
        /// <param name="filePath">Path to the customizations file to import</param>
        public void ImportAllXml(string importXml)
        {
            // Create the request.
            ImportAllXmlRequest importRequest = new ImportAllXmlRequest();

            // Tell the request where the temporary XML file is located.
            importRequest.CustomizationXml = importXml;

            // Execute the import.
            ImportAllXmlResponse importResponse = (ImportAllXmlResponse)this.Service.Execute(importRequest);
        }
        #endregion

        #region Export
        /// <summary>
        /// Exports Customization
        /// </summary>
        /// <returns>XML string with all exported customizations</returns>
        public string Export(string parameterXML)
        {

            ExportXmlRequest request = new ExportXmlRequest();
            request.ParameterXml = parameterXML.ToLower();

            ExportXmlResponse response;
            response = Service.Execute(request) as ExportXmlResponse;

            return response.ExportXml;
        }
        #endregion

        #region ExportAll
        /// <summary>
        /// Exports Customization
        /// </summary>
        /// <returns>XML string with all exported customizations</returns>
        public string ExportAll()
        {
            ExportAllXmlRequest request = new ExportAllXmlRequest();
            ExportAllXmlResponse response;
            
            try
            {
                response = Service.Execute(request) as ExportAllXmlResponse;
            }
            catch
            {
                response = Service.Execute(request) as ExportAllXmlResponse;
            }

            return response.ExportXml;
        }
        #endregion

        #region ExportAll
        /// <summary>
        /// Export all customizations to specified file (.zip only).
        /// </summary>
        /// <param name="filePath">File name where save exported customizations in .zip format</param>
        public void ExportAll(string filePath)
        {
            // Create the request.
            ExportCompressedAllXmlRequest request = new ExportCompressedAllXmlRequest();

            // Assign the file name for the customizations.
            request.EmbeddedFileName = "customizations.xml";

            // Execute the request.
            ExportCompressedAllXmlResponse response = (ExportCompressedAllXmlResponse)this.Service.Execute(request);

            // Get the compressed data.
            byte[] compressedXML = response.ExportCompressedXml;

            // Write the data to disk.
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                fs.Write(compressedXML, 0, compressedXML.Length);
                fs.Close();
            }
        }
        #endregion

        #region Publish
        /// <summary>
        /// Publish customization 
        /// </summary>
        /// <returns>True if customization was published successfully</returns>
        public bool Publish(string parameterXML)
        {
            PublishXmlRequest request = new PublishXmlRequest();
            request.ParameterXml = parameterXML;
            PublishXmlResponse response = this.Service.Execute(request) as PublishXmlResponse;
            return response != null;
        }
        #endregion

        #region PublishAll
        /// <summary>
        /// Publish all customizations
        /// </summary>
        public void PublishAll()
        {
            PublishAllXmlRequest request = new PublishAllXmlRequest();
            this.Service.Execute(request);
        }
        #endregion
    }
}
